

package jm.lib.collections.list;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;


/**
 * 
 * A faked list for DisplayTag which do not need create the full list which 
 * might cause waste of memory and other resources
 * 
 * @author JimingLiu
 *
 */ 
public class PageList<T> implements List<T> {
	private static final String NOT_SUPPORTED = "Not supported!";
	private int size;
	private int startIndex;
	private int endIndex;
	private int pageSize;
	private ArrayList<T> list;
	
	private PageList() {};
	
	/**
	 * 
	 * @param pageItems Items for the page
	 * @param totalItemsCount total items count
	 * @param startIndex start index of the page
	 */
	public PageList(List<T> pageItems, int totalItemsCount, int startIndex, int pageSize) {
		list = new ArrayList<T>(pageItems); 
		this.startIndex = startIndex>0?startIndex:0;
		this.endIndex = this.startIndex + list.size();
		this.pageSize = pageSize;
		size = totalItemsCount>endIndex?totalItemsCount:endIndex;
	}
	
	public int size() {
		return this.size;
	}

	public boolean isEmpty() {
		return this.size>0;
	}

	public boolean contains(Object o) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public Iterator<T> iterator() {
		return new PageIterator();
	}

	public Object[] toArray() {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

    @SuppressWarnings("hiding")
	public <T> T[] toArray(T[] a) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public boolean add(Object arg0) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public boolean remove(Object o) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public boolean containsAll(Collection arg0) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public boolean addAll(Collection arg0) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public boolean addAll(int arg0, Collection arg1) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public boolean removeAll(Collection arg0) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public boolean retainAll(Collection arg0) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public void clear() {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public T get(int index) {
		if(index < this.startIndex || index >= endIndex ) {
			return null;
		} else {
			return list.get(index - startIndex);
		}
		
	}

	public T set(int arg0, T arg1) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public void add(int arg0, Object arg1) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public T remove(int index) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public int indexOf(Object o) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public int lastIndexOf(Object o) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public ListIterator<T> listIterator() {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public ListIterator<T> listIterator(int index) {
		throw new UnsupportedOperationException(NOT_SUPPORTED);
	}

	public List<T> subList(int fromIndex, int toIndex) {
		return list;
	}
	
	public int getPageSize() {
		return this.pageSize;
	}


	class PageIterator implements Iterator<T>{
		private int cursor = 0;

		public boolean hasNext() {
			return cursor < size();
		}

		public T next() {
			return get(cursor++);
		}


		public void remove() {
			throw new UnsupportedOperationException(NOT_SUPPORTED);			
		}
		
	}

}
